Lists and Tuples

Lists Recap

A list is a sequence of values. These values can be anything: strings, numbers, booleans, even other lists.

To make a list you put the items separated by commas between brackets []


In [42]:
sushi_order = ['unagi', 'hamachi', 'otoro']
prices = [6.50, 5.50, 15.75]
print(sushi_order)
print(prices)


['unagi', 'hamachi', 'otoro']
[6.5, 5.5, 15.75]

You can access a single element in a list by indexing in using brackets. List indexing starts at 0 so to get the first element, you use 0, the second element is 1 and so on.

list[index]


In [12]:
print(sushi_order[0])
print(sushi_order[2])


unagi
otoro

You can find the length of a list using len

len(list)


In [15]:
print(len(sushi_order))


3

You can use negative indexing to get the last element of a list


In [20]:
print(sushi_order[-3])


unagi

Nested lists

Lists can contain other lists as elements. This is a convenient alternative to a matrix. You can arrange lists of varying lengths (and contents) in a specific order and you can iterate over the elements (see below).


In [21]:
everyones_order = [['california roll'], ['unagi', 'dragon roll'], sushi_order]
print(everyones_order)


[['california roll'], ['unagi', 'dragon roll'], ['unagi', 'hamachi', 'otoro']]

To access an element in a nested list, first index to the inner list, then index to the item.

Example:

    list_of_lists = [[1,2], [3,4], []]

Acess the first index to the inner list and index to the item

inner_list = list_of_lists[1] # [3,4]
    print inner_list[0] # 3

Or even quicker:

list_of_lists[1][0] # 3

TRY IT

1) To get dragon roll from the sushi order, first we get the second element (index 1) then we get the the second item (index 1)


In [22]:



Out[22]:
'dragon roll'

2) Print california roll from the list everyones_order:


In [23]:



Out[23]:
'california roll'

3) Print all items from the second person's order


In [25]:



Out[25]:
['unagi', 'dragon roll']

Mutable Lists

Lists are mutable, that means that you can change elements.

To assign a new value to an element

my_list = [1, 2, 3]
my_list[0] = 100

In [26]:
sushi_order[0] = 'caterpillar roll'
print(sushi_order)


['caterpillar roll', 'hamachi', 'otoro']

TRY IT

Update the last element in prices to be 21.00 and print out the new result


In [32]:
prices[-1] = 21.00
print(prices)


[6.5, 5.5, 21.0]

Operators and Lists

The in operator allows you to see if an element is contained in a list


In [34]:
sushi_order


Out[34]:
['caterpillar roll', 'hamachi', 'otoro']

In [36]:
print(('hamachi' in sushi_order))


True

In [37]:
if 'otoro' in sushi_order:
    print("Big spender!")


Big spender!

You can use some arithmatic operators on lists

The + operator concatenates two lists

The * operator duplicates a list that many times


In [24]:
print((sushi_order * 3))


['caterpillar roll', 'hamachi', 'otoro', 'caterpillar roll', 'hamachi', 'otoro', 'caterpillar roll', 'hamachi', 'otoro']

In [38]:
exprep = ['rep'+str(i) for i in range(5)]
exprep


Out[38]:
['rep0', 'rep1', 'rep2', 'rep3', 'rep4']

In [38]:
print((prices + sushi_order))


[6.5, 5.5, 15.75, 'unagi', 'hamachi', 'otoro']

Note: You can only concatenate lists with lists! If you want to add a "non-list" element you can use the append() function.


In [43]:
newprices = prices.copy()
newprices.append(22)
print(newprices)


[6.5, 5.5, 15.75, 22]

In [44]:
prices


Out[44]:
[6.5, 5.5, 15.75]

Remember slices from strings? We can also use the slice operator on lists


In [45]:
inexpensive = sushi_order[:2] #takes only the first two elements from list
print(inexpensive)


['unagi', 'hamachi']

Don't forget, you can use the for and in keywords to loop through a list


In [47]:
for item in sushi_order:
    print(("I'd like to order the {}.".format(item)))
    
print("And hold the wasabi!")


I'd like to order the unagi.
I'd like to order the hamachi.
I'd like to order the otoro.
And hold the wasabi!

In [52]:
for ind, item in enumerate(sushi_order):
    print(("I'd like to order the {0} for {1}.".format(item, prices[ind])))


I'd like to order the unagi for 6.5.
I'd like to order the hamachi for 5.5.
I'd like to order the otoro for 15.75.

TRY IT

Create a variable called lots_of_sushi that repeats the inexpensive list two times


In [54]:
lots_of_sushi = inexpensive*2
print(lots_of_sushi)


['unagi', 'hamachi', 'unagi', 'hamachi']

Adding and deleting elements

To add an element to a list, you have a few options

  1. the append method adds an element or elements to the end of a list, if you pass it a list, the next element with be a list (making a list of lists)

  2. the extend method takes a list of elements and adds them all to the end, not creating a list of lists

  3. use the + operator like you saw before


In [69]:
my_sushis = ['maguro', 'rock n roll']
my_sushis.append('avocado roll')
print(my_sushis)
my_sushis.append(['hamachi', 'california roll'])
print(my_sushis)


['maguro', 'rock n roll', 'avocado roll']
['maguro', 'rock n roll', 'avocado roll', ['hamachi', 'california roll']]

In [70]:
my_sushis = ['maguro', 'rock n roll']
my_sushis.extend(['hamachi', 'california roll'])
print(my_sushis)


['maguro', 'rock n roll', 'hamachi', 'california roll']

You also have several options for removing elements

  1. the pop method takes the index of the element to remove and returns the value of the element

  2. the remove method takes the value of the element to remove

  3. the del operator deletes the element or slice of the list that you give it

    del l[1:]


In [71]:
print(my_sushis)
last_sushi = my_sushis.pop(-1)
print(last_sushi)


['maguro', 'rock n roll', 'hamachi', 'california roll']
california roll

In [72]:
my_sushis.remove('maguro')
print(my_sushis)


['rock n roll', 'hamachi']

In [73]:
del my_sushis[1:]
print(my_sushis)


['rock n roll']

TRY IT

Add 'rock n roll' to sushi_order then delete the first element of sushi_order


In [ ]:

List Functions

max will return maximum value of list

min returns minimum value of list

sum returns the sum of the values in a list

len returns the number of elements in a list # Just a reminder


In [55]:
numbers = [1, 1, 2, 3, 5, 8]

print((max(numbers)))
print((min(numbers)))
print((sum(numbers)))
print((len(numbers)))


8
1
20
6

TRY IT

Find the average of numbers using list functions (and not a loop!)


In [57]:
sum(numbers)/len(numbers)


Out[57]:
3.3333333333333335

Aliasing

If you assign a list to another variable, it will still refer to the same list. This can cause trouble if you change one list because the other will change too.


In [62]:
cooked_rolls = ['unagi roll', 'shrimp tempura roll']
my_order = cooked_rolls
my_order.append('hamachi')
print(my_order)
print(cooked_rolls)


['unagi roll', 'shrimp tempura roll', 'hamachi']
['unagi roll', 'shrimp tempura roll', 'hamachi']

To check this, you can use the is operator to see if both variable refer to the same object


In [63]:
print((my_order is cooked_rolls))


True

To fix this, you can make a copy of the list using the list function

list takes a sequence and turns it into a list.

Alternatively you can use the copy() method: my_order = cooked_rolls.copy()


In [64]:
cooked_rolls = ['unagi roll', 'shrimp tempura roll']
my_order = list(cooked_rolls)
my_order.append('hamachi')
print(my_order)
print(cooked_rolls)


['unagi roll', 'shrimp tempura roll', 'hamachi']
['unagi roll', 'shrimp tempura roll']

Tuples

Tuples are very similar to lists. The major difference is that tuples are immutable meaning that you can not add, remove, or assign new values to a tuple.

The creator of a tuple is the comma , but by convention people usually surround tuples with parenthesis.


In [65]:
noodles = ('soba', 'udon', 'ramen', 'lo mein', 'somen', 'rice noodle')
print((type(noodles)))


<class 'tuple'>

You can create a tuple from any sequence using the tuple function


In [68]:
sushi_tuple = tuple(my_order)
print(sushi_tuple)
# Remember strings are sequences
maguro = tuple('maguro')
print(maguro)


('unagi roll', 'shrimp tempura roll', 'hamachi')
('m', 'a', 'g', 'u', 'r', 'o')

To create a single element tuple, you need to add a comma to the end of that element (it looks kinda weird)


In [85]:
single_element_tuple = (1,)
print(single_element_tuple)
print((type(single_element_tuple)))


(1,)
<class 'tuple'>

You can use the indexing and slicing you learned for lists the same with tuples.

But, because tuples are immutable, you cannot use the append, pop, del, extend, or remove methods or even assign new values to indexes


In [69]:
print((noodles[0]))
print((noodles[4:]))


soba
('somen', 'rice noodle')

In [70]:
# This should throw an error
noodles[0] = 'spaghetti'


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-70-a6e00963cc15> in <module>()
      1 # This should throw an error
----> 2 noodles[0] = 'spaghetti'

TypeError: 'tuple' object does not support item assignment

To change the values in a tuple, you need to create a new tuple (there is nothing stopping you from assigning it to the same variable, though


In [71]:
print(sushi_tuple)
sushi_tuple = sushi_tuple[1:] + ('california roll',)
print(sushi_tuple)


('unagi roll', 'shrimp tempura roll', 'hamachi')
('shrimp tempura roll', 'hamachi', 'california roll')

You can loop through tuples the same way you loop through lists, using for in


In [72]:
for noodle in noodles:
    print(("Yummy, yummy {0} and {1}".format(noodle, 'sushi')))


Yummy, yummy soba and sushi
Yummy, yummy udon and sushi
Yummy, yummy ramen and sushi
Yummy, yummy lo mein and sushi
Yummy, yummy somen and sushi
Yummy, yummy rice noodle and sushi

TRY IT

Create a tuple containing 'soy sauce' 'ginger' and 'wasabi' and save it in a variable called accompaniments


In [ ]:

Zip

the zip function takes any number of lists of the same length and returns a list of tuples where the tuples will contain the i-th element from each of the lists.

This is really useful when combining lists that are related (especially for looping)


In [73]:
print((list(zip([1,2,3], [4,5,6]))))


[(1, 4), (2, 5), (3, 6)]

In [74]:
sushi = ['salmon', 'tuna', 'sea urchin']
prices = [5.5, 6.75, 8]

sushi_and_prices = list(zip(sushi, prices))

sushi_and_prices


Out[74]:
[('salmon', 5.5), ('tuna', 6.75), ('sea urchin', 8)]

In [101]:
for sushi, price in sushi_and_prices:
    print(("The {0} costs ${1}".format(sushi, price)))


The salmon costs $5.5
The tuna costs $6.75
The sea urchin costs $8

Enumerate

While the zip function iterates over two lists, the built-in function enumerate loops through indices and elements of a list. It returns a list of tuples containing the index and value of that element.

for index, value in enumerate(list):
    ...

In [111]:
exotic_sushi = ['tako', 'toro', 'uni', 'hirame']
for index, item in enumerate(exotic_sushi):
    print((index, item))


0 tako
1 toro
2 uni
3 hirame

Project: Party Budget

You are tasked with writing budgeting software, but at this point, things are a mess. You have two files. budget_prices.txt has a list of costs for each item separated by new lines (\n). budget_items.txt has a list of the items that were bought. Luckily they are both in order. You need to write a program that will take the files and a value for the overall budget and print out the total spent and how close they are to reaching the budget. In step 2 you will create a new file where the items and prices are in the same document and there is a sum printed out at the end.

Step 1

  1. Create a function called file_to_float_list that takes in a file and returns a list containing a float for each line Hint Make sure to remove the newlines when casting as floats.
  2. Store the budget of 2000.00 in a variable called budget.
  3. Run file_to_float_list on budget_prices.txt and save the result in a variable called prices.
  4. Calculate the sum of the prices array and store in a variable called spent.
  5. Calculate the percentage of budget spent and store in a variable called percent_spent
  6. Print out the results:

    Budget: 2000.00 Spent: (amt spent) Percentage Spent: (percent spent)

  7. Bonus Print out a progress bar for the budget. Print out '=' for every 10% spent and '-' for every 10% unspent. =====>-----

Step 2

  1. Create a function called file_to_string_list that takes in a file and returns a list containing a string for each line with newlines removed.
  2. Run file_to_string_list on budget_items.txt and save the result in a variable called stuff_bought.
  3. Zip stuff_bought and prices together and store in a variable called items_and_prices
  4. Loop through items_and_prices and print out the item, then a tab character '\t' and then the price (use string formatting)
  5. Print another line 'Sum\t(amount spent)'
  6. Print a final line 'Budget\t(budget)'

  7. Bonus Print everything you printed for step 2 into a new file. (Then open the file in excel.)


In [ ]: